home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assemblers / cas.lha / orig / das.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-10  |  13.7 KB  |  393 lines

  1. #include <stdio.h>
  2.  
  3. typedef unsigned char byte;
  4. typedef unsigned int word;
  5.  
  6. byte Arg[3];
  7. word PC; byte Generating;
  8. byte Ref[0x4000], Hex[0x4000];
  9. #define ENTRY 0x80
  10. #define OP    0x40
  11. #define ARG   0x20
  12. #define LINKS 0x1f
  13.  
  14. word Paged(byte P) {
  15.    return PC&0xf800 | (Arg[0]&0xe0) << 3 | P;
  16. };
  17.  
  18. word Relative(byte R) {
  19.    return PC + (signed char)R;
  20. };
  21.  
  22. word Entries[0x100], *EP = Entries;
  23.  
  24. void PUSH(word Address) {
  25.    byte B = Ref[Address]&LINKS;
  26.    if (Ref[Address]&ARG) {
  27.       fprintf(stderr, "Entry into ARG at %04x.\n", PC); return;
  28.    }
  29.    if (++B <= LINKS) Ref[Address] = Ref[Address]&~LINKS | B;
  30.    if (Ref[Address]&ENTRY) return;
  31.    Ref[Address] |= ENTRY;
  32.    if (Ref[Address]&OP) return;
  33.    if (EP - Entries == 0x100) {
  34.       fprintf(stderr, "Too many entries, PC = %04x.\n", PC); exit(1);
  35.    }
  36.    *EP++ = Address;
  37. };
  38.  
  39. byte Xs[0x100] = {
  40.  1, 14, 15,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  41.  7,  6,  7,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  42.  7, 14,  9,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  43.  7,  6,  9,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  44.  6, 14,  2,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  45.  6,  6,  2,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  46.  6, 14,  2,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  47.  6,  6,  2, 25,  2,  3,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
  48. 14, 14,  2,  1,  1,  3,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
  49.  3,  6,  2,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  50.  2, 14,  2,  1,  1,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
  51.  2,  6,  2,  1,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
  52.  2, 14,  2,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  53.  2,  6,  2,  1,  1,  7,  1,  1,  6,  6,  6,  6,  6,  6,  6,  6,
  54.  1, 14,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  55.  1,  6,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1
  56. };
  57.  
  58. char *Ns[0x100] = {
  59. "nop",           "ajmp %P",  "ljmp %L",     "rr A",
  60.    "inc A",          "inc %D",         "inc %i",          "inc %i",
  61.    "inc %n",          "inc %n",          "inc %n",          "inc %n",
  62.    "inc %n",          "inc %n",          "inc %n",          "inc %n",
  63. "jbc %B, %R",    "acall %P", "lcall %L",    "rrc A",
  64.    "dec A",          "dec %D",         "dec %i",          "dec %i",
  65.    "dec %n",          "dec %n",          "dec %n",          "dec %n",
  66.    "dec %n",          "dec %n",          "dec %n",          "dec %n",
  67. "jb %B, %R",     "ajmp %P",  "ret",         "rl A",
  68.    "add A, %I",      "add A, %D",      "add A, %i",       "add A, %i",
  69.    "add A, %n",       "add A, %n",       "add A, %n",       "add A, %n",
  70.    "add A, %n",       "add A, %n",       "add A, %n",       "add A, %n",
  71. "jnb %B, %R",    "acall %P", "reti",        "rlc A",
  72.    "addc A, %I",     "addc A, %D",     "addc A, %i",      "addc A, %i",
  73.    "addc A, %n",      "addc A, %n",      "addc A, %n",      "addc A, %n",
  74.    "addc A, %n",      "addc A, %n",      "addc A, %n",      "addc A, %n",
  75. "jc %R",         "ajmp %P",  "orl %D, A",   "orl %D, %I",
  76.    "orl A, %I",      "orl A, %D",      "orl A, %i",       "orl A, %i",
  77.    "orl A, %n",       "orl A, %n",       "orl A, %n",       "orl A, %n",
  78.    "orl A, %n",       "orl A, %n",       "orl A, %n",       "orl A, %n",
  79. "jnc %R",        "acall %P", "anl %D, A",   "anl %D, %I",
  80.    "anl A, %I",      "anl A, %D",      "anl A, %i",       "anl A, %i",
  81.    "anl A, %n",       "anl A, %n",       "anl A, %n",       "anl A, %n",
  82.    "anl A, %n",       "anl A, %n",       "anl A, %n",       "anl A, %n",
  83. "jz %R",         "ajmp %P",  "xrl %D, A",   "xrl %D, %I",
  84.    "xrl A, %I",      "xrl A, %D",      "xrl A, %i",       "xrl A, %i",
  85.    "xrl A, %n",       "xrl A, %n",       "xrl A, %n",       "xrl A, %n",
  86.    "xrl A, %n",       "xrl A, %n",       "xrl A, %n",       "xrl A, %n",
  87. "jnz %R",        "acall %P", "orl C, %B",   "jmp @A+DPTR",
  88.    "mov A, %I",      "mov %D, %I",     "mov %i, %I",      "mov %i, %I",
  89.    "mov %n, %I",      "mov %n, %I",      "mov %n, %I",      "mov %n, %I",
  90.    "mov %n, %I",      "mov %n, %I",      "mov %n, %I",      "mov %n, %I",
  91. "sjmp %R",       "ajmp %P",  "anl C, %B",   "movc A, @A+PC",
  92.    "div AB",         "mov %2D, %1D",   "mov %D, %i",      "mov %D, %i",
  93.    "mov %D, %n",      "mov %D, %n",      "mov %D, %n",      "mov %D, %n",
  94.    "mov %D, %n",      "mov %D, %n",      "mov %D, %n",      "mov %D, %n",
  95. "mov DPTR, %W",  "acall %P", "mov %B, C",   "movc A, @A+DPTR",
  96.    "subb A, %I",     "subb A, %D",     "subb A, %i",      "subb A, %i",
  97.    "subb A, %n",      "subb A, %n",      "subb A, %n",      "subb A, %n",
  98.    "subb A, %n",      "subb A, %n",      "subb A, %n",      "subb A, %n",
  99. "orl C, /%B",    "ajmp %P",  "mov C, %B",   "inc DPTR",
  100.    "mul AB",         "ERROR",          "mov %i, %D",      "mov %i, %D",
  101.    "mov %n, %D",      "mov %n, %D",      "mov %n, %D",      "mov %n, %D",
  102.    "mov %n, %D",      "mov %n, %D",      "mov %n, %D",      "mov %n, %D",
  103. "anl C, /%B",    "acall %P", "cpl %B",      "cpl C",
  104.    "cjne A, %I, %R", "cjne A, %D, %R", "cjne %i, %I, %R", "cjne %i, %I, %R",
  105.    "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R",
  106.    "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R",
  107. "push %D",       "ajmp %P",  "clr %B",      "clr C",
  108.    "swap A",         "xch A, %D",      "xch A, %i",       "xch A, %i",
  109.    "xch A, %n",       "xch A, %n",       "xch A, %n",       "xch A, %n",
  110.    "xch A, %n",       "xch A, %n",       "xch A, %n",       "xch A, %n",
  111. "pop %D",        "acall %P", "setb %B",     "setb C",
  112.    "da A",           "djnz %D, %R",    "xchd A, %i",      "xchd A, %i",
  113.    "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",
  114.    "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",
  115. "movx A, @DPTR", "ajmp %P",  "movx A, @R0", "movx A, @R1",
  116.    "clr A",          "mov A, %D",      "mov A, %i",       "mov A, %i",
  117.    "mov A, %n",       "mov A, %n",       "mov A, %n",       "mov A, %n",
  118.    "mov A, %n",       "mov A, %n",       "mov A, %n",       "mov A, %n",
  119. "movx @DPTR, A", "acall %P", "movx @R0, A", "movx @R1, A",
  120.    "cpl A",          "mov %D, A",      "mov %i, A",       "mov %i, A",
  121.    "mov %n, A",       "mov %n, A",       "mov %n, A",       "mov %n, A",
  122.    "mov %n, A",       "mov %n, A",       "mov %n, A",       "mov %n, A"
  123. };
  124.  
  125. void PrintByte(byte B) {
  126.    if (B >= 0xa0) putchar('0');
  127.    printf("%02xh", B);
  128. }
  129.  
  130. void PrintWord(word W) {
  131.    if (W >= 0xa000) putchar('0');
  132.    printf("%04xh", W);
  133. }
  134.  
  135. char *SFRs[0x80] = {
  136.   "P0", "SP", "DPL", "DPH", 0, 0, 0, "PCON",
  137.   "TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", 0, 0,
  138.   "P1", 0, 0, 0, 0, 0, 0, 0, "SCON", "SBUF", 0, 0, 0, 0, 0, 0,
  139.   "P2", 0, 0, 0, 0, 0, 0, 0, "IE", 0, 0, 0, 0, 0, 0, 0,
  140.   "P3", 0, 0, 0, 0, 0, 0, 0, "IP", 0, 0, 0, 0, 0, 0, 0,
  141.   0, 0, 0, 0, 0, 0, 0, 0, "T2CON", 0, "RCAP2L", "RCAP2H", "TL2", "TH2", 0, 0,
  142.   "PSW", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  143.   "ACC", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  144.   "B", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  145. };
  146.  
  147. void PrintData(byte D) { /* THIS ASSUMES THE 8052 */
  148.    if (!Generating) return;
  149.    if (D < 0x80 || SFRs[D - 0x80] == 0) { PrintByte(D); return; }
  150.    printf(SFRs[D - 0x80]);
  151. }
  152.  
  153. char *Bits[0x80] = {
  154.    0, 0, 0, 0, 0, 0, 0, 0,
  155.    "IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1",
  156.    "T2", "T2EX", 0, 0, 0, 0, 0, 0,
  157.    "RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0",
  158.    0, 0, 0, 0, 0, 0, 0, 0,
  159.    "EX0", "ET0", "EX1", "ET1", "ES", "ET2", 0, "EA",
  160.    "RXD", "TXD", "INT0", "INT1", "T0", "T1", "WR", "RD",
  161.    "PX0", "PT0", "PX1", "PT1", "PS", "PT2", 0, 0,
  162.    0, 0, 0, 0, 0, 0, 0, 0,
  163.    "CP_RL2", "C_T2", "TR2", "EXEN2", "TCLK", "RCLK", "EXF2", "TF2",
  164.    "P", 0, "OV", "RS0", "RS1", "F0", "AC", "CY", 0, 0, 0, 0, 0, 0, 0, 0,
  165.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  166.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  167. };
  168.  
  169. void PrintBit(byte B) {
  170.    byte Byte, Bit;
  171.    if (!Generating) return;
  172.    if (B < 0x80) { PrintByte(B); return; }
  173.    B -= 0x80;
  174.    if (Bits[B] != 0) { printf(Bits[B]); return; }
  175.    Byte = B&0x78; Bit = B&0x07;
  176.    if (SFRs[Byte] != 0) { printf("%s.%1x", SFRs[Byte], Bit); return; }
  177.    PrintByte((byte)(B + 0x80));
  178. }
  179.  
  180. void PrintImmByte(byte B) {
  181.    if (!Generating) return;
  182.    putchar('#'); PrintByte(B);
  183. }
  184.  
  185. void PrintImmWord(word W) {
  186.    if (!Generating) return;
  187.    putchar('#'); PrintWord(W);
  188. }
  189.  
  190. byte CheckSum; word HighAddr;
  191.  
  192. byte Nib(int X) {
  193.    if (X >= '0' && X <= '9') return X - '0';
  194.    if (X >= 'a' && X <= 'f') return X - 'a' + 10;
  195.    if (X >= 'A' && X <= 'F') return X - 'A' + 10;
  196.    fprintf(stderr, "Bad hexadecimal digit in input.\n");
  197.    exit(1);
  198. }
  199.  
  200. byte GetHex(void) {
  201.    int A, B; byte Bt;
  202.    A = getchar(); B = getchar();
  203.    if (A == EOF || B == EOF) {
  204.       fprintf(stderr, "Unexpected EOF.\n"); exit(1);
  205.    }
  206.    Bt = Nib(A) << 4 | Nib(B);
  207.    CheckSum = (CheckSum + Bt)&0xff; return Bt;
  208. }
  209.  
  210. word GetWord(void) {
  211.    word A, B;
  212.    A = GetHex(); B = GetHex();
  213.    return (A << 8) | B;
  214. }
  215.  
  216. void HexLoad(void) {
  217.    int Ch, I;
  218.    byte Size, Mark, CheckSum; word Addr;
  219.    byte Buffer[0x10];
  220.    HighAddr = 0;
  221.    while (1) {
  222.       do {
  223.          Ch = getchar();
  224.          if (Ch == EOF) { fprintf(stderr, "Unexpected EOF.\n"); exit(1); }
  225.       } while (Ch != ':');
  226.       CheckSum = 0;
  227.       Size = GetHex(); Addr = GetWord(); Mark = GetHex();
  228.       for (I = 0; I < Size; I++) Buffer[I] = GetHex();
  229.       (void)GetHex();
  230.       if (CheckSum != 0) {
  231.          fprintf(stderr, "Bad checksum.\n"); exit(1);
  232.       }
  233.       if (Mark) break;
  234.       if (Addr >= 0x4000 - Size) {
  235.          printf("Address out of range 0 - 4000h in input.\n"); exit(0);
  236.       }
  237.       for (I = 0; I < Size; I++, Addr++) Hex[Addr] = Buffer[I], Ref[Addr] = 0;
  238.       if (Addr > HighAddr) HighAddr = Addr;
  239.       (void)getchar();
  240.    }
  241. }
  242.  
  243. #define IN_RANGE(A) ((A) >= 0x0000 && (A) < HighAddr)
  244.  
  245. word Address;
  246. void PutLabel(word PC) {
  247.    byte B;
  248.    if (!Generating) Address = PC;
  249.    else {
  250.       if (PC >= 0x4000) { PrintWord(PC); return; }
  251.       B = (Ref[PC]&LINKS) + 'A';
  252.       printf("%c%04x", B, PC);
  253.    }
  254. }
  255.  
  256. void MakeOp(char *S) {
  257.    int A; byte B;
  258.    for (A = 1; *S != '\0'; S++) {
  259.       if (*S != '%') {
  260.          if (Generating) putchar(*S);
  261.          continue;
  262.       }
  263.       S++;
  264.       if (*S >= '0' && *S <= '2') A = *S++ - '0';
  265.       switch (*S) {
  266.          case 'L': B = Arg[A++]; PutLabel(B << 8 | Arg[A++]); break;
  267.          case 'P': PutLabel(Paged(Arg[A++])); break;
  268.          case 'R': PutLabel(Relative(Arg[A++])); break;
  269.          case 'D': PrintData(Arg[A++]); break;
  270.          case 'B': PrintBit(Arg[A++]); break;
  271.          case 'I': PrintImmByte(Arg[A++]); break;
  272.          case 'W': B = Arg[A++]; PrintImmWord(B << 8 | Arg[A++]); break;
  273.          case 'i': if (Generating) printf("@R%1x", Arg[0]&1); break;
  274.          case 'n': if (Generating) printf("R%1x", Arg[0]&7); break;
  275.          default:
  276.             fprintf(stderr, "Bad format string, PC = %04x.\n", PC);
  277.          exit(1);
  278.       }
  279.    }
  280.    if (Generating) putchar('\n');
  281.    else if (!IN_RANGE(Address)) printf("REF: %04x\n", Address);
  282.    else PUSH(Address);
  283. }
  284.  
  285. int Disassemble(void) {
  286.    byte B; byte Mode; char *Name; int I;
  287.    if (Ref[PC]&ARG) {
  288.       fprintf(stderr, "OP into ARG at %04x.\n", PC++); return 1;
  289.    }
  290.    if (Generating) {
  291.       if (Ref[PC]&ENTRY) { PutLabel(PC); printf(":\n"); }
  292.    } else {
  293.       if (Ref[PC]&OP) { PC++; return 1; }
  294.       Ref[PC] |= OP;
  295.    }
  296.    Arg[0] = B = Hex[PC++];
  297.    Mode = Xs[B]; Name = Ns[B];
  298.    for (I = 1; I < (Mode&3); I++) {
  299.       if (Ref[PC]&OP) {
  300.          fprintf(stderr, "ARG into OP at %04x.\n", PC); return 1;
  301.       }
  302.       if (!Generating) {
  303.          if (Ref[PC]&ARG) {
  304.             fprintf(stderr, "ARG into ARG at %04x.\n", PC); return 1;
  305.          }
  306.          Ref[PC] |= ARG;
  307.       }
  308.       Arg[I] = Hex[PC++];
  309.    }
  310.    if (Generating) {
  311.       if (!(Mode&8)) printf("   ");
  312.       MakeOp(Name);
  313.    } else {
  314.       if (Mode&4) MakeOp(Name);
  315.       if (Mode&0x10) {
  316.          printf("Indirect jump at %04x\n", PC - (Mode&3));
  317.       }
  318.    }
  319.    return (!Generating && (Mode&8) || Generating && !Ref[PC]);
  320. }
  321.  
  322. void PCHAR(byte B) { putchar((B < 0x20 || B >= 0x7f)? ' ': B); }
  323.  
  324. int Ended; FILE *EntryF;
  325.  
  326. byte fGetHex(void) {
  327.    int A, B;
  328.    if (Ended) return 0;
  329.    A = fgetc(EntryF); B = fgetc(EntryF);
  330.    if (A == EOF || B == EOF) { Ended = 1; return 0; }
  331.    return Nib(A) << 4 | Nib(B);
  332. }
  333.  
  334. word fGetWord(void) {
  335.    word A, B;
  336.    A = fGetHex(); B = fGetHex();
  337.    (void)fgetc(EntryF);
  338.    if (Ended) return 0;
  339.    return (A << 8) | B;
  340. }
  341.  
  342. void main(void) {
  343.    word *E, W;
  344.    HexLoad();
  345. fprintf(stderr, "First pass\n");
  346.    Generating = 0;
  347.    EntryF = fopen("entries", "r");
  348.    if (EntryF == NULL) {
  349.       fprintf(stderr, "No entry points listed.\n"); exit(1);
  350.    }
  351.    for (Ended = 0, EP = Entries; !Ended; ) {
  352.       W = fGetWord(); if (!Ended) PUSH(W);
  353.    }
  354.    while (EP > Entries) {
  355.       PC = *--EP;
  356.       while (!Disassemble());
  357.    }
  358. fprintf(stderr, "Second pass\n");
  359.    Generating = 1;
  360.    if (Ref[0]) printf("org 0\n");
  361.    for (PC = 0x00; IN_RANGE(PC); ) {
  362.       byte F, Buf[16];
  363.       if (!Ref[PC]) {
  364.          printf("DATA AT "); PrintWord(PC); putchar('\n');
  365.          for (F = 0; !Ref[PC] && IN_RANGE(PC); PC++) {
  366.             Buf[F++] = Hex[PC];
  367.             if (F == 16) {
  368.                for (F = 0; F < 16; F++) {
  369.                   printf("%2x", Buf[F]);
  370.                   if (F < 15) putchar(' '); else putchar('|');
  371.                }
  372.                for (F = 0; F < 16; F++) PCHAR(Buf[F]);
  373.                putchar('|'); putchar('\n');
  374.                F = 0;
  375.             }
  376.          }
  377.          if (F > 0) {
  378.             byte F1;
  379.             for (F1 = 0; F1 < F; F1++) printf("%2x ", Buf[F1]);
  380.             for (; F1 < 16; F1++) {
  381.                Buf[F1] = 0;
  382.                printf("  "); if (F1 < 15) putchar(' '); else putchar('|');
  383.             }
  384.             for (F = 0; F < 16; F++) PCHAR(Buf[F]);
  385.             putchar('|'); putchar('\n');
  386.          }
  387.          if (!IN_RANGE(PC)) break;
  388.          printf("org "); PrintWord(PC); putchar('\n');
  389.       }
  390.       while (!Disassemble());
  391.    }
  392. }
  393.